import os
import md5
import urllib
from method import Method, Param, KeywordParam, String, Boolean, Integer

class ApplyWatermark(Method):
    """
    Arguments:
    Integer ImageID
    Integer WatermarkID
    """
    
    name = 'smugmug.images.applyWatermark'
    params = (
       Param('ImageID', Integer), 
       Param('WatermarkID', Integer)
    )
    
applyWatermark = ApplyWatermark()

class RemoveWatermark(Method):
    """
    Arguments:
    Integer ImageID
    """

    name = 'smugmug.images.removeWatermark'
    params = (
       Param('ImageID', Integer),
    )
    
removeWatermark = RemoveWatermark()

class Crop(Method):
    """
    Arguments:
    Integer ImageID
    Integer Width
    Integer Height
    Integer X
    Integer Y
    """

    name = 'smugmug.images.crop'
    params = (
        Param('ImageID', Integer),
        Param('Width', Integer),
        Param('Height', Integer),
        Param('X', Integer),
        Param('Y', Integer)
    )

crop = Crop()

class Rotate(Method):
    """
    Arguments:
    Integer Degrees
    Boolean Flip
    """

    name = 'smugmug.images.rotate'
    params = (
        Param('Degrees', Integer),
        Param('Flip', Boolean)
    )

rotate = Rotate()

class ZoomThumbnail(Method):
    """
    Arguments:
    Integer ImageID
    Integer Width
    Integer Height
    Integer X
    Integer Y
    """

    name = 'smugmug.images.zoomThumbnail'
    params = (
        Param('ImageID', Integer),
        Param('Width', Integer),
        Param('Height', Integer),
        Param('X', Integer),
        Param('Y', Integer)
    )

zoomThumbnail = ZoomThumbnail()

class Get(Method):
    """
    This method will fetch all the ImageIDs for the album specified by AlbumID.
    The Album must be owned by the Session holder, or else be Public (if
    password-protected, a Password must be provided), to return results..
    Otherwise, an "invalid user" faultCode will result.

    Arguments:
    Integer AlbumID
    Boolean Heavy (optional)
    String Password (optional)
    String SitePassword (optional)
    """

    name = 'smugmug.images.get'
    params = (
        Param('AlbumID', Integer),
    )
    keywordParams = (
        KeywordParam('Heavy', Boolean),
        KeywordParam('Password', String),
        KeywordParam('SitePassword', String)
    )
    responseKey = 'Images'

get = Get()

class GetUrls(Method):
    """
    This method will return all the URLs for the various sizes of the image
    specified by ImageID. The Album must be owned by the Session holder, or
    else be Public (if password-protected, a Password must be provided), to
    return results. Otherwise, an "invalid user" faultCode will result.
    Additionally, obvious restrictions on Originals and Larges apply if so
    set by the owner. They will return as empty strings for those URLs if
    they're unavailable.

    Arguments:
    Integer ImageID
    Integer TemplateID (optional) -- specifies which Style to build the 
      AlbumURL with. (default 3)
    String Password (optional)
    String SitePassword (optional)    
    """

    name = 'smugmug.images.getURLs'
    params = (
        Param('ImageID', Integer),
    )
    keywordParams = (
        KeywordParam('TemplateID', Integer),
        KeywordParam('Password', String),
        KeywordParam('SitePassword', String)
    )

getURLs = GetUrls()

class GetInfo(Method):
    """
    This method will return details about the image specified by ImageID. The
    Album must be owned by the Session holder, or else be Public (if
    password-protected, a Password must be provided), to return results..
    Otherwise, an "invalid user" faultCode will result. Additionally, some
    fields are only returned to the Album owner.

    Arguments:
    Integer ImageID
    String Password (optional)
    String SitePassword (optional)
    """

    name = 'smugmug.images.getInfo'
    params = (
        Param('ImageID', Integer),
    )
    keywordParams = (
        KeywordParam('Password', String),
        KeywordParam('SitePassword', String)
    )
    responseKey = 'Image'

getInfo = GetInfo()

class GetExif(Method):
    """
    This method will return camera and photograph details about the image
    specified by ImageID. The Album must be owned by the Session holder, or
    else be Public (if password-protected, a Password must be provided), to
    return results. Otherwise, an "invalid user" faultCode will result.
    Additionally, the album owner must have specified that EXIF data is
    allowed. Note that many photos have no EXIF data, so an empty or
    partially returned result is very normal.

    Arguments:
    Integer ImageID
    String Password (optional)
    String SitePassword (optional)
    """

    name = 'smugmug.images.getEXIF'
    params = (
        Param('ImageID', Integer),
    )
    keywordParams = (
        KeywordParam('Password', String),
        KeywordParam('SitePassword', String)
    )

getEXIF = GetExif()

class ChangeSettings(Method):
    """
    This method updates specific settings for a given image specified by
    ImageID. If any of the parameters are missing or are empty strings "",
    they're ignored and the current settings are preserved. Otherwise,
    they're updated with the new settings. This method can be used to update
    Captions, Keywords, or to move an image from one Album to another.

    Arguments:
    Integer ImageID
    Integer AlbumID (optional)
    String Caption (optional)
    String Keywords (optional)
    """

    name = 'smugmug.images.changeSettings'
    params = (
        Param('ImageID', Integer),
    )
    keywordParams = (
        KeywordParam('AlbumID', Integer),
        KeywordParam('Caption', String),
        KeywordParam('Keywords', String)
    )

changeSettings = ChangeSettings()

class ChangePosition(Method):
    """
    This method changes the Position of an image within it's Album.

    Arguments:
    Integer ImageID
    Integer Position
    """

    name = 'smugmug.images.changePosition'
    params = (
        Param('ImageID', Integer),
        Param('Position', Integer)
    )

changePosition = ChangePosition()

class Upload(Method):
    """
    This method will upload a file to the specified Album (identified by
    AlbumID) with the required parameters.

    Arguments:
    Integer AlbumID
    String FileName
    """

    name = 'smugmug.images.upload'
    params = (
        Param('AlbumID', Integer),
        Param('FileName', String),
    )    
    keywordParams = (
        KeywordParam('ImageID', Integer),
        KeywordParam('Keywords', String),
        KeywordParam('Latitude', String),
        KeywordParam('Longitude', String),
        KeywordParam('Altitude', String),
        KeywordParam('Caption', String)
    )
    
    def _get_request(self, smuggler, params):
        if not os.path.exists(params['FileName']):
            raise Exception('Could not find image file "%s".' % params['FileName'])
            
        f = file(params['FileName'], 'r')
        fileBody = f.read()
        f.close()
        
        contentLength = len(fileBody)
        contentMd5 = md5.new(fileBody).hexdigest()
        params['FileName'] = os.path.basename(params['FileName'])
        headers = {
            'Content-Length' : contentLength,
            'Content-MD5' : contentMd5,
        }
        
        return Request(None, uri=smuggler.apiUploadUri + urllib.urlencode(params['FileName']), params=params, body=fileBody, useSsl=self.useSsl, httpMethod='PUT')
    
upload = Upload()

class UploadFromUrl(Method):
    """
    This method will upload a file from a specified URL to the specified Album
    (identified by AlbumID) with the required parameters.

    Arguments:
    Integer AlbumID
    String Caption
    String URL
    String Keywords (optional) -- Keywords should be separated by a semi-colon.
    String Latitude (optional) -- Latitude of the image in the form D.d, such
      as 37.430096
    String Longitude (optional) -- Longitude of the image in the form D.d, such
      as -122.152269
    String Altitude (optional) -- Altitude of the image in meters
    Integer ByteCount (optional) -- The # of bytes in the file. Used to ensure
      upload completed properly
    String MD5Sum (optional) -- The md5 hash of the file being uploaded. Used
      to ensure upload completed properly
    """

    name = 'smugmug.images.uploadFromURL'
    params = (
        Param('AlbumID', Integer),
        Param('Caption', String),
        Param('URL', String),
    )
    keywordParams = (
        KeywordParam('Keywords', String),
        KeywordParam('Latitude', String),
        KeywordParam('Longitude', String),
        KeywordParam('Altitude', String),
        KeywordParam('ByteCount', Integer),
        KeywordParam('MD5Sum', String)
    )

uploadFromURL = UploadFromUrl()

class Delete(Method):
    """
    This method deletes the specified Image.

    Arguments:
    Integer ImageID
    """

    name = 'smugmug.images.delete'
    params = (
        Param('ImageID', Integer),
    )

delete = Delete()

class GetStats(Method):
    """
    Gets transfer statitistics for the given Image during the given Month.
    SmugMug often only keeps the current month and the one previous, but you
    never know. :)

    Arguments:
    Integer ImageID
    Integer Month
    """

    name = 'smugmug.images.getStats'
    params = (
        Param('ImageID', Integer),
        Param('Month', Integer)
    )

getStats = GetStats()
